Data Typing and Operators
Different computer languages impose different constraints on programmers creating computer programs. Typing is one area in which constraints may be imposed by a computer language. Typing refers to the assignment to a variable of a specific data type. Expressions which are evaluated will also be of a specific data type.
Data types may be built-in to the language (often, for example, built-in types include String, Integer, and Long types). Types which are built in to the language are known as intrinsic types. In addition to intrinsic types, in some languages, data types may be defined by a user. The data type of a programming element refers to what kind of data it can hold and how that data is stored. Data types apply to all values that can be stored in computer memory or participate in the evaluation of an expression.
In many languages, built-in and user-defined operators are also provided. An operator performs some pre-defined operation on one or more expressions. For example, in one language, an operator “+” may be a binary operator. A binary operator works on two expressions. In most languages, an expression may be a constant, a variable, or a more complex expression. Expressions have types, and operators are defined to work on specific types. Thus the “bar” operator may be defined only over expressions of type Integer, allowing the operation “x bar y” only if x and y are both Integer type. An operator may also be defined in different cases. For example the operator “foo” may be defined for “x foo y” in all situations shown in Table 1:
TABLE 1Possible types for x and y in expression “x foo y”Type for xType for yResultIntegerIntegerIntegerStringStringStringDoubleDoubleDouble
The “foo” operator thus can be used with several different types, as shown above. When an operator may be used with operands of different types, it is termed an overloaded operator. When the foo operator is used with a first and second operand that are of type Integer, the result is an Integer. As another example of operators which can work on operands of different types, in a given language the “+” operator can be used both to add integers and to concatenate strings. A user who has defined a user-defined type may also define an operation for use with that user-defined type.
Overloading a method allows a programmer to keep an interface consistent, and allows the programmer to logically call the same method regardless of the types of data being passed in. Using the same name promotes simplicity—it lets a programmer remember what a procedure does, as opposed to having to come up with new names or a naming convention to help keep things straight.
A language may specify (or allow user-defined specification of) a way of changing a value from one data type to another data type. This process is called type conversion. Type conversion is also known as “casting.” An important characteristic of a type conversion is whether the result of the conversion is within the range of the destination data type. A widening conversion changes a value from one data type to another data type, where the second data type can accommodate any possible value of the original data. A narrowing conversion changes a value from a first data type to a second data type, where that second data type might not be able to hold some of the possible values which can be expressed in the first data type. Thus, in a narrowing conversion, data might be lost.
The following Table 2 shows an example of standard widening conversions, in this case conversions which are standard in the Visual Basic language:
TABLE 2Widening Conversions in Visual BasicData typeWidens to data typesByteByte, Short, Integer, Long, Decimal, Single, DoubleShortShort, Integer, Long, Decimal, Single, DoubleIntegerInteger, Long, Decimal, Single, DoubleLongLong, Decimal, Single, DoubleDecimalDecimal, Single, DoubleSingleSingle, DoubleDoubleDoubleAny enumeratedIts underlying integer type and any type to whichtypethat widensCharChar, StringAny typeObjectAny derived typeAny base type from which it is derivedAny typeAny interface it implements
Conversions from Integer to Single, from Long to Single or Double, or from Decimal to Single or Double might result in loss of precision, but never in loss of magnitude. In this sense they do not incur information loss.
As seen in Table 2, a conversion from a derived type to one of its base types is widening. This is because the derived type contains all the members of the base type, so it qualifies as an instance of the base type. In the opposite direction, the base type does not have the members defined by the derived type.
Some standard narrowing conversions include:                The reverse directions of the widening conversions        Conversions in either direction between Boolean and any numeric type        Any numeric type to any enumerated type        Conversions in either direction between a Char( ) array and a String        Conversions in either direction between String and any numeric type, Boolean, or Date        Conversions from a data type or object type to a type derived from it        
In some languages, including Visual Basic, when users are allowed to create user-defined types, users can also define narrowing and widening conversions to or from these user-defined types. These conversions may be to or from other user-defined types, or to or from intrinsic types.
Typing of Languages and Operator Overloading
A strongly-typed language is a computer language in which there can not be type-inconsistencies. The compiler for a strongly-typed language will examine each expression in a program being compiled, and will verify that the expression does not attempt to use an operator with inconsistent expressions. An expression which includes inconsistent types will likely trigger a compilation error, and the compiler will return with errors rather than completing the compilation of the program.
If a language is not strongly-typed, expressions may be inconsistently typed. This allows more flexibility for a user. However, if the language is not strongly-typed, a compiler must have some way of determining how to evaluate an inconsistent expression. One way to do this is by using widening conversions. In the example of the “foo” operator discussed above, if the loosely-typed language encounters the expression “byte1 foo byte2”, where byte1 and byte2 are of type Byte, the expression is inconsistently typed, as can be seen by referring to Table 1, which does not include an entry for using foo with two expressions of type Byte. However, if there is a widening conversion from Byte to Integer (as there is, for example, in Visual Basic, see Table 2) then this conversion can be used, and the operation can be completed.
However, where a user-defined type is used, and the user has not defined the operator over the user-defined type, this resolution will fail. This is irrespective of whether the user defined type has a conversion to any of the intrinsic types for which this operator is defined.
In order to provide flexibility for users, a language may maintain a commitment to allowing certain operators to be used with a wide number of types, including user-defined types. When this is not possible, the language fails in its commitment. Further, where users of a language must explicitly decide how user-defined types will work with specific operators, more work must be done by a user to produce a functional program in the language.
In view of the foregoing there is a need for a system that overcomes the drawbacks of the prior art.